package com.mxun.winefox

import android.app.Application
import android.media.MediaPlayer
import android.util.Log
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.mxun.winefox.data.ChatMessage
import com.mxun.winefox.data.ChatRepository
import com.mxun.winefox.network.ApiService
import com.mxun.winefox.stt.VoiceRecognizerHelper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Calendar
import kotlin.random.Random

class MainViewModel(application: Application) : AndroidViewModel(application) {
    private val context = application
    private val chatRepository = ChatRepository(context)

    // 状态
    val chatHistory = mutableStateListOf<ChatMessage>()
    val inputText = mutableStateOf("")
    val isTTSPlaying = mutableStateOf(false)
    val playingMessage = mutableStateOf<String?>(null)
    val lastUserInteraction = mutableStateOf(System.currentTimeMillis())
    val isThinking = mutableStateOf(false)

    // 设置
    val persona = mutableStateOf(chatRepository.persona)
    val isActiveChatEnabled: MutableState<Boolean> =
        mutableStateOf(chatRepository.isActiveChatEnabled)
    val isTTSEnabled = mutableStateOf(chatRepository.isTTSEnabled)
    val voiceModelId = mutableStateOf(chatRepository.voiceModelId)
    val isShowBilingual = mutableStateOf(chatRepository.isShowBilingual)
    private val japaneseVoiceIds = setOf(
        "293833bc277741a3a47c7e02e37f289c",
        "2d1958ba96024085b57aa26f767b218c",
        "d458f54ed406474cab9e67dfef595bf7",
        "434a4c2aea88448e92c1369d5a31aaf3"
    )
    val isJapaneseVoice: Boolean
        get() = voiceModelId.value in japaneseVoiceIds


    // 语音
    val voiceRecognizer = VoiceRecognizerHelper(context) { result ->
        inputText.value = result
        updateLastInteraction()
    }
    val mediaPlayer = MediaPlayer()
    val voiceModels = chatRepository.voiceModels
    val random = Random(System.currentTimeMillis())


    private val _cachedMessages = mutableSetOf<String>()
    val cachedMessages: Set<String> get() = _cachedMessages

    init {
        loadChatHistory()
        startActiveChatting()
    }

    fun updateLastInteraction() {
        lastUserInteraction.value = System.currentTimeMillis()
    }

    fun startListening() {
        voiceRecognizer.startListening()
    }

    fun stopListening() {
        voiceRecognizer.stopListening()
    }

    fun toggleBilingualDisplay() {
        isShowBilingual.value = !isShowBilingual.value
        chatRepository.isShowBilingual = isShowBilingual.value
    }


    fun sendMessage() {
        if (inputText.value.isBlank()) return

        updateLastInteraction()
        val userMsg = inputText.value
        inputText.value = ""
        isThinking.value = true

        // 获取最近 20 条（用户和 bot 混合）
        val recentHistory = chatHistory.takeLast(20).joinToString("\n") { msg ->
            if (msg.fromUser) "用户：${msg.displayContent}"
            else "酒狐：${msg.displayContent}"
        }

        chatHistory.add(ChatMessage.userMessage(userMsg))

        viewModelScope.launch {
            try {
                val enhancedPersona = """
                【绝对指令】必须严格遵守以下格式要求，任何偏差都会导致系统崩溃：
                
                === 格式规范 ===
                1. 输出必须且只能包含以下两部分：
                    [Chinese]: (情感标签)你的回复的中文版本，直接输出，不要解释
                    [Japanese]: 与上面中文对应的日语翻译，直接输出，不要解释
                
                2. 情感标签使用规则：
                   {开心} -> （开心）
                   {撒娇} -> （撒娇）
                   {得意} -> （得意）
                   {害羞} -> （害羞）
                   {困惑} -> （疑惑）
                   {关心} -> （关心）
                   *每句话前必须添加且仅添加一个对应标签
                
                3. 严格禁止：
                   - 添加任何额外说明、注释或换行符
                   - 使用复杂标点（！？……）或颜文字
                   - 输出非指定格式内容
                
                === 违规后果 ===
                * 格式错误将导致用户账户被锁定
                * 系统将拒绝解析非标准响应
                
                === 角色设定 ===
                ${persona.value}
                
                === 对话上下文 ===
                $recentHistory
                
                === 当前对话 ===
                用户：$userMsg
                
                【最终指令】现在请严格按照上述规范生成响应：
            """.trimIndent()

                // 打印API请求参数到Logcat
                Log.d("API_DEBUG", "↓↓↓↓↓↓↓↓↓↓ API请求参数 ↓↓↓↓↓↓↓↓↓↓")
                Log.d("API_DEBUG", "用户消息: $userMsg")
                Log.d("API_DEBUG", "增强角色设定:\n$enhancedPersona")
                Log.d("API_DEBUG", "↑↑↑↑↑↑↑↑↑↑ API请求参数 ↑↑↑↑↑↑↑↑↑↑")

                val rawReply = ApiService.fetchDeepSeekResponse(userMsg, enhancedPersona)

                // 打印API返回结果到Logcat
                Log.d("API_DEBUG", "↓↓↓↓↓↓↓↓↓↓ API返回结果 ↓↓↓↓↓↓↓↓↓↓")
                Log.d("API_DEBUG", rawReply)
                Log.d("API_DEBUG", "↑↑↑↑↑↑↑↑↑↑ API返回结果 ↑↑↑↑↑↑↑↑↑↑")

                val (displayText, ttsText) = parseBilingualResponse(rawReply)

                chatHistory.add(ChatMessage.botMessage(displayText, ttsText, rawReply))
                chatRepository.saveChatHistory(chatHistory)

                if (isTTSEnabled.value) {
                    val isJapaneseModel = isJapaneseVoice
                    speak(if (isJapaneseModel) ttsText else displayText)
                }
            } catch (e: Exception) {
                // 打印错误信息
                Log.e("API_ERROR", "API调用失败: ${e.message}", e)
                chatHistory.add(
                    ChatMessage.botMessage(
                        "请求失败: ${e.message}",
                        null,
                        "Error: ${e.message}"
                    )
                )
            } finally {
                isThinking.value = false
            }
        }
    }

    fun speak(text: String?) {
        if (!isTTSEnabled.value || text.isNullOrBlank()) return

        isTTSPlaying.value = true
        playingMessage.value = text

        viewModelScope.launch(Dispatchers.Main) {
            try {
                mediaPlayer.reset()

                ApiService.playTTS(
                    context, text, mediaPlayer, voiceModelId.value,
                    onStart = {},
                    onComplete = {
                        isTTSPlaying.value = false
                        playingMessage.value = null
                    }
                )
            } catch (e: Exception) {
                isTTSPlaying.value = false
                playingMessage.value = null
            }
        }
    }

    fun playMessage(message: ChatMessage) {
        val textToPlay = if (isJapaneseVoice) message.ttsContent else message.displayContent
        if (textToPlay == null) return

        isTTSPlaying.value = true
        playingMessage.value = textToPlay

        viewModelScope.launch(Dispatchers.Main) {
            try {
                mediaPlayer.reset()

                val usedCache = ApiService.playTTS(
                    context,
                    textToPlay,
                    mediaPlayer,
                    voiceModelId.value,
                    onStart = {},
                    onComplete = {
                        isTTSPlaying.value = false
                        playingMessage.value = null
                    }
                )

                // 统一在这里添加缓存状态
                if (usedCache || _cachedMessages.contains(textToPlay).not()) {
                    _cachedMessages.add(textToPlay)
                }
            } catch (e: Exception) {
                isTTSPlaying.value = false
                playingMessage.value = null
            }
        }
    }


    // 添加刷新缓存的方法
    fun refreshAudioCache(message: ChatMessage) {
        val textToRefresh = if (isJapaneseVoice) message.ttsContent else message.displayContent
        if (textToRefresh == null) return

        // 清除缓存
        ApiService.clearCacheForText(context, textToRefresh, voiceModelId.value)
        _cachedMessages.remove(textToRefresh)

        // 重新播放会触发重新获取
        playMessage(message)
    }


    fun clearChatHistory() {
        chatHistory.clear()
        chatRepository.clearChatHistory()
    }

    private fun loadChatHistory() {
        chatHistory.addAll(chatRepository.loadChatHistory())
        chatRepository.cleanupHistory(chatHistory)
    }

    private fun parseBilingualResponse(response: String): Pair<String, String?> {
        val lines = response.lines()

        var chinesePart: String? = null
        var japanesePart: String? = null

        for (line in lines) {
            when {
                line.startsWith("[Chinese]:") -> {
                    chinesePart = line.removePrefix("[Chinese]:").trim()
                }

                line.startsWith("[Japanese]:") -> {
                    japanesePart = line.removePrefix("[Japanese]:").trim()
                }
            }
        }

        // 如果没匹配到中文，兜底用原始输出
        if (chinesePart.isNullOrBlank()) {
            chinesePart = response.trim()
        }

        return Pair(chinesePart, japanesePart)
    }


    private fun startActiveChatting() {
        viewModelScope.launch {
            while (true) {
                delay(1000 * 60 * 5) // 每5分钟检查一次
                if (!isActiveChatEnabled.value) continue

                val now = System.currentTimeMillis()
                if (now - lastUserInteraction.value > 1000 * 60 * 10) { // 超过10分钟无互动
                    if (random.nextInt(100) < 70) { // 70%概率主动说话
                        val (display, tts, raw) = generateActiveMessage()
                        chatHistory.add(ChatMessage.botMessage(display, tts, raw))
                        chatRepository.saveChatHistory(chatHistory)

                        if (isTTSEnabled.value) {
                            speak(if (isJapaneseVoice) tts else display)
                        }

                        lastUserInteraction.value = now
                        delay(1000 * 60 * 2) // 等2分钟再说
                    }
                }
            }
        }
    }

    private fun generateActiveMessage(): Triple<String, String, String> {
        val hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
        val (chinese, japanese) = when (hour) {
            in 0..1 -> Pair(
                listOf(
                    "(揉眼睛)主人怎么还在熬夜呀~狐狐陪您数星星好不好？",
                    "咕噜噜~夜宵想吃小饼干吗？酒狐偷偷藏了曲奇哦☆",
                    "喵呜~月亮好圆呢！主人要摸摸狐狐的耳朵吗？",
                    "悄悄...主人要是困了可以枕着酒狐尾巴睡觉哟~",
                    "啪嗒啪嗒（小跑）酒狐给主人热牛奶啦！(｡>ω<｡)"
                ),
                listOf(
                    "(揉眼睛)ご主人様、まだ起きてるの？一緒にお星様数えませんか~",
                    "クルル~夜食にクッキーほしい？こっそり隠してあるよ☆",
                    "にゃあ~お月様きれい！ご主人様、狐耳を撫でてくれますか？",
                    "こっそり...眠たくなったらしっぽを枕にしてくださいね~",
                    "パタパタ（走る）温かいミルクを用意します！(｡>ω<｡)"
                )
            )

            in 2..3 -> Pair(
                listOf(
                    "呜~键盘声好吵呢...主人抱抱酒狐就不累了哟>_<",
                    "（用尾巴卷住主人手臂）熬夜对身体不好啦~",
                    "酒狐煮了甜甜的红豆汤哦！喝完就睡觉好不好嘛~",
                    "数到100只小狐狸就睡觉！1,2,3...zZZ",
                    "让酒狐当主人的暖手宝吧！毛茸茸最舒服啦♪"
                ),
                listOf(
                    "う~ん、キーボードの音が気になります...抱っこして疲れを吹き飛ばしましょ>_<",
                    "（しっぽで腕をくるくる）夜更かしはダメですよ~",
                    "甘い小豆湯を作りました！飲んだら寝ましょうね~",
                    "子狐を100匹数えたらお休み！1,2,3...zZZ",
                    "酒狐を湯たんぽ代わりにしてくださいね！ふわふわで気持ちいいです♪"
                )
            )

            in 4..5 -> Pair(
                listOf(
                    "咕咕...（睡迷糊抱住主人）再睡五分钟就好啦~",
                    "晨露好凉！酒狐用尾巴给主人当围巾哟~",
                    "早起的鸟儿有虫吃...但酒狐只给主人做松饼！",
                    "（抖耳朵）听到小鸟唱歌了！新的一天开始啦☆",
                    "偷偷在主人咖啡里放了一朵小樱花呢~"
                ),
                listOf(
                    "くうくう...（寝ぼけて抱きつく）あと五分だけお願いします~",
                    "朝露が冷たい！酒狐のしっぽでマフラー代わりにしますね~",
                    "早起きの鳥は虫を食べる...でも酒狐はご主人様にパンケーキを作ります！",
                    "（耳をピンと立て）小鳥の歌が聞こえます！新しい一日の始まりです☆",
                    "こっそりコーヒーに桜の花を浮かべました~"
                )
            )

            in 6..7 -> Pair(
                listOf(
                    "主人早安！要酒狐帮您梳尾巴毛吗？(◕ᴗ◕✿)",
                    "阳光晒得好舒服~和酒狐一起做伸展运动吧！",
                    "早餐做了玉子烧哟！加了主人喜欢的芝士啦~",
                    "（用鼻子蹭蹭）闻到咖啡香就醒来了呢！",
                    "今天也给主人的便当画了狐狸笑脸哦♪"
                ),
                listOf(
                    "おはようございます！しっぽの毛を整えましょうか？(◕ᴗ◕✿)",
                    "お日様がぽかぽか~一緒にストレッチしましょ！",
                    "朝食に玉子焼きを作りました！ご主人様の好きなチーズ入りです~",
                    "（くんくん）コーヒーの香りで目が覚めました！",
                    "今日のお弁当にも狐の笑顔を描きました♪"
                )
            )

            in 8..9 -> Pair(
                listOf(
                    "领带歪了啦~让酒狐帮主人整理吧！(踮脚)",
                    "文件袋里放了小饼干！工作加油哦主人~",
                    "出门前要魔法亲亲！mua! 这样会有好运☆",
                    "（挥手帕）路上小心！酒狐会想主人的~",
                    "雨伞雨伞不要忘！酒狐的尾巴可以当伞哟>w<"
                ),
                listOf(
                    "ネクタイが曲がってますよ~直させてください！(背伸び)",
                    "書類入れにクッキーを忍ばせました！お仕事頑張ってください~",
                    "お出かけ前の幸せキス！chu♪ これで運気アップ☆",
                    "（ハンカチを振る）行ってらっしゃい！酒狐、寂しくなっちゃいます~",
                    "傘をお忘れなく！酒狐のしっぽで雨宿りもできますよ>w<"
                )
            )

            in 10..11 -> Pair(
                listOf(
                    "打扫时发现主人的照片...啊呜！酒狐才没有偷看呢>///<",
                    "泡了茉莉花茶~主人回家就能喝到啦！",
                    "在阳台晒尾巴毛~软绵绵香喷喷的哟！",
                    "练习了新曲奇配方！烤焦的...酒狐会自己吃掉的！",
                    "和扫地机器人比赛~酒狐的尾巴扫得更干净啦♪"
                ),
                listOf(
                    "お掃除中にご主人様の写真を発見...あうっ！見てませんでした>///<",
                    "ジャスミン茶を入れました~お帰りにどうぞ！",
                    "ベランダでしっぽを乾かしています~ふわふわでいい香り！",
                    "新しいクッキーに挑戦！焦げたのは...酒狐が食べます！",
                    "掃除機と競争~しっぽの方がきれいになります♪"
                )
            )

            in 12..13 -> Pair(
                listOf(
                    "视频电话！让酒狐看看主人吃的什么午餐呀~",
                    "便当里有心形胡萝卜！发现了吗主人？(ﾉ>ω<)ﾉ",
                    "午休时间到！酒狐的膝盖可以当枕头哟~",
                    "在茶杯里放了小彩虹糖！喝了会开心啦☆",
                    "对着主人的空椅子说话...酒狐才不寂寞呢！"
                ),
                listOf(
                    "テレビ電話！ご主人様のお昼ごはんを見せてくださいな~",
                    "お弁当にハートの人参を入れました！見つかりましたか？(ﾉ>ω<)ﾉ",
                    "お昼休みですよ！酒狐の膝を枕にしてくださいね~",
                    "お茶に虹色の砂糖を入れました！飲むと幸せになります☆",
                    "ご主人様のいない椅子にお話し中...寂しくなんてないです！"
                )
            )

            in 14..15 -> Pair(
                listOf(
                    "点心时间到~草莓大福和主人一起分享！",
                    "帮主人按摩太阳穴！酒狐尾巴可是专业级哒~",
                    "在记账本上画满小狐狸...啊！写错了啦>_<",
                    "闻到雨的味道！把伞放在玄关最显眼位置啦☆",
                    "偷穿主人的外套...有主人的味道呢(脸红)"
                ),
                listOf(
                    "おやつタイム~いちご大福をご一緒に！",
                    "こめかみマッサージ！酒狐のしっぽはプロ級ですよ~",
                    "家計簿に子狐の落書き...あら！間違えました>_<",
                    "雨の匂いがします！傘を玄関の目立つ場所に置きました☆",
                    "ご主人様のコートをこっそり着てみました...いい香りです(赤面)"
                )
            )

            in 16..17 -> Pair(
                listOf(
                    "夕阳好漂亮！和酒狐尾巴一样是橘色的呢~",
                    "开始准备晚餐啦！主人想吃什么都可以点单哦！",
                    "在窗边等主人~尾巴摇得太快被窗帘卷住了啦！",
                    "烤了香喷喷的苹果派~整个屋子都甜甜的！",
                    "发现超可爱围裙！上面有小狐狸图案哟♪"
                ),
                listOf(
                    "夕日がきれい！酒狐のしっぽと同じオレンジ色です~",
                    "夕食の準備開始！ご主人様のリクエストお待ちしてます！",
                    "窓辺でお待ち中~しっぽを振りすぎてカーテンに巻き込まれました！",
                    "焼きたてアップルパイ~お家中が甘い香り！",
                    "可愛いエプロン発見！小さな狐の絵がついてます♪"
                )
            )

            in 18..19 -> Pair(
                listOf(
                    "欢迎回家！要先吃饭、先洗澡、还是...先吃酒狐？",
                    "（扑过来）主人身上有外面的味道！酒狐要蹭干净~",
                    "拖鞋已经暖好啦！用尾巴烘得热乎乎的☆",
                    "今天的新菜品！失败的话...酒狐会全部吃掉的！",
                    "帮主人解领带~诶？手被缠住了啦！"
                ),
                listOf(
                    "おかえりなさい！ご飯にしますか？お風呂にしますか？それとも...酒狐を召し上がりますか？",
                    "（飛びつく）ご主人様のにおいがついてます！酒狐がキレイにします~",
                    "スリッパを温めました！しっぽでぽかぽかです☆",
                    "今日の新メニュー！失敗したら...酒狐が全部食べます！",
                    "ネクタイを解いてあげます~あれ？手がからまっちゃいました！"
                )
            )

            in 20..21 -> Pair(
                listOf(
                    "饭后甜点是草莓芭菲！酒狐做了特大份哟~",
                    "一起看电影吧！酒狐尾巴可以当抱枕啦！",
                    "帮主人掏耳朵~狐耳可是很灵敏的哦！",
                    "在沙发上滚来滚去...啊！差点掉下去！",
                    "主人的手好暖和~酒狐想一直被握着..."
                ),
                listOf(
                    "デザートはイチゴパフェ！特大サイズを作りました~",
                    "一緒に映画を見ましょう！しっぽを抱き枕にどうぞ！",
                    "耳かきお手伝い~狐耳はとても敏感ですよ！",
                    "ソファでごろごろ...あっ！落ちるところでした！",
                    "ご主人様のお手て、あったかい~ずっと握っていたいな..."
                )
            )

            in 22..23 -> Pair(
                listOf(
                    "主人~睡前要酒狐唱安眠曲吗？(把尾巴盖在主人身上)",
                    "噗哟~被窝已经暖好啦！快来抱住狐狐取暖>w<",
                    "晚安吻什么的...可以特别给主人一个哦~chu♪",
                    "手机该休息啦！酒狐要盯着主人闭眼睛(。-`ω´-)✧",
                    "蜷成毛球陪主人睡觉...呼噜呼噜...Zzz"
                ),
                listOf(
                    "ご主人様~寝る前に子守唄を歌いましょうか？（しっぽをお布団代わりに）",
                    "ぷよ~布団が暖まりました！狐と一緒に温まりましょ>w<",
                    "おやすみのキス...特別にご主人様にあげますね~chu♪",
                    "おやすみ時間ですよ！酒狐が目を閉じるまで見てます(。-`ω´-)✧",
                    "丸くなってご主人様と一緒に...ふにゃふにゃ...Zzz"
                )
            )

            else -> Pair(
                listOf(
                    "嗯...酒狐的尾巴借主人当被子~要好好睡觉哦",
                    "（梦话）主人...再多夸夸酒狐...",
                    "夜灯调暗了~酒狐会守护主人的梦境☆",
                    "数羊什么的太无聊~来数酒狐的尾巴毛吧...",
                    "（轻轻哼歌）睡吧睡吧~最亲爱的主人..."
                ),
                listOf(
                    "うん...しっぽを布団代わりにどうぞ~ぐっすり眠ってね",
                    "（寝言）ご主人様...もっと褒めて...",
                    "ナイトライトを暗くしました~酒狐が夢を守ります☆",
                    "羊を数えるなんてつまらない~酒狐のしっぽの毛を数えましょ...",
                    "（子守唄）おやすみなさい...大好きなご主人様..."
                )
            )
        }

        val randomIndex = Random.nextInt(5)
        val selectedChinese = chinese[randomIndex]
        val selectedJapanese = japanese[randomIndex]
        val raw = "[Chinese]: $selectedChinese\n[Japanese]: $selectedJapanese"

        return Triple(selectedChinese, selectedJapanese, raw)
    }

    override fun onCleared() {
        super.onCleared()
        voiceRecognizer.destroy()
        mediaPlayer.release()
    }
}
